home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / cppsum.zip / CPPSUM.CPP next >
C/C++ Source or Header  |  1994-06-18  |  9KB  |  262 lines

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // DLL functions to get summary info from OLE 2.0 document files.
  4. //
  5. //    Copyright ⌐ 1994 Somar Software, All Rights Reserved
  6. //    Send problem reports and comments to 72202.2574@compuserve.com
  7. //            
  8. // See cppsum.h for further documentation and change log.
  9. //                 
  10.  
  11. #define STRICT
  12. #include <windows.h>
  13. #include <memory.h>
  14. #include <ole2ver.h>      
  15. #include <storage.h>
  16. #include <compobj.h>
  17. #include "cppsum.h"                                        
  18.  
  19. // a temporary function was unreferenced and then removed by optimization
  20. // causing warning 4505
  21. #pragma warning(disable:4505) 
  22.  
  23. ///////////////////////////////////////////////////////////////////////////
  24. #define VT_I4           3
  25. #define VT_LPSTR        30
  26. #define VT_FILETIME     64
  27.  
  28. typedef struct _PROPVALUE {
  29.    DWORD vtType;
  30.    union {
  31.       FILETIME      vtTime;  
  32.       LONG          vtLong;
  33.       struct {
  34.          DWORD cBytes;
  35.          char  ch[1];
  36.       } vtBSTR;
  37.    } vtValue;
  38. } PROPVALUE;
  39. typedef PROPVALUE FAR * LPPROPVALUE;
  40.  
  41. typedef struct _SUMMARYINFO {
  42.    DWORD   cBytes;
  43.    DWORD   cProps;
  44.    struct {
  45.       DWORD propID;
  46.       DWORD dwOffset;
  47.       } aProps[1];
  48. } SUMMARYINFO;
  49. typedef SUMMARYINFO FAR * LPSUMINFO;
  50.  
  51. LPPROPVALUE FindProperty(HANDLE hSumInfo, DWORD pid);
  52.  
  53. ///////////////////////////////////////////////////////////////////////////
  54. extern "C" WORD FAR PASCAL __export SumInfoInit()
  55. {
  56.    DWORD dwVer = CoBuildVersion();
  57.    if (rmm != HIWORD(dwVer)) return 0;
  58.  
  59.    HRESULT hr = CoInitialize(NULL);
  60.    SCODE scode = GetScode(hr);
  61.    if (scode == S_OK) return 1;
  62.    if (scode == S_FALSE) return 2;
  63.    return 0;
  64. }
  65.  
  66. ///////////////////////////////////////////////////////////////////////////
  67. extern "C" void FAR PASCAL __export SumInfoUninit(WORD wInitStatus)
  68. {
  69.    if (wInitStatus == 1)
  70.       CoUninitialize();
  71. }   
  72.  
  73. ///////////////////////////////////////////////////////////////////////////
  74. extern "C" HANDLE FAR PASCAL __export SumInfoOpenFile(LPSTR szPath)
  75. {
  76.    BOOL            bResult = FALSE;
  77.    LPSUMINFO       lpSumInfo;
  78.    DWORD           i;       
  79.    DWORD           dwBytesInSection;
  80.    HRESULT         hr;
  81.    ULONG           ulBytesRead;                      
  82.    LARGE_INTEGER   li;                 
  83.    LPSTREAM        pIStream;
  84.    LPSTORAGE       pIStorage;
  85.    HGLOBAL         hglb = NULL;
  86.  
  87.    struct {
  88.       WORD     byteOrder;
  89.       WORD     wFormat;
  90.       WORD     osVersion1;
  91.       WORD     osVersion2;
  92.       CLSID    classId;
  93.       DWORD    cSections;
  94.    } PropHeader;
  95.    struct {
  96.       DWORD dwords[4];
  97.       DWORD dwOffset;
  98.    } FIDAndOffset;
  99.  
  100.    hr = StgOpenStorage(szPath, NULL, 
  101.                       STGM_READ | STGM_SHARE_DENY_NONE | STGM_PRIORITY,
  102.                       NULL, 0, &pIStorage);
  103.    if (FAILED(hr)) return NULL;
  104.        
  105.    hr = pIStorage->OpenStream("\005SummaryInformation", NULL,
  106.                     STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  107.    if (FAILED(hr)) goto ReleaseStorage;
  108.          
  109.    LISet32(li, 0);
  110.    hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
  111.    if (hr != NOERROR) goto ReleaseStream;
  112.    
  113.    hr = pIStream->Read(&PropHeader, 28, &ulBytesRead);
  114.    if (hr != NOERROR || ulBytesRead != 28) goto ReleaseStream;
  115.  
  116.    if (PropHeader.byteOrder != 0xFFFE) goto ReleaseStream;
  117.    if (PropHeader.wFormat != 0) goto ReleaseStream;
  118.    
  119.    for (i = 0; i < PropHeader.cSections; i++) {
  120.       hr = pIStream->Read(&FIDAndOffset, 20, &ulBytesRead);
  121.       if (hr != NOERROR || ulBytesRead != 20) goto ReleaseStream;
  122.       if (FIDAndOffset.dwords[0] == 0XF29F85E0 && 
  123.           FIDAndOffset.dwords[1] == 0X10684FF9 &&
  124.           FIDAndOffset.dwords[2] == 0X000891AB &&
  125.           FIDAndOffset.dwords[3] == 0XD9B3272B) break;
  126.    }
  127.    if (i >= PropHeader.cSections) goto ReleaseStream;
  128.  
  129.    LISet32(li, FIDAndOffset.dwOffset);
  130.    hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
  131.    if (hr != NOERROR) goto ReleaseStream;
  132.    
  133.    hr = pIStream->Read(&dwBytesInSection, 4, &ulBytesRead);
  134.    if (hr != NOERROR || ulBytesRead != 4) goto ReleaseStream;
  135.                                                 
  136.    hglb = GlobalAlloc(GPTR, dwBytesInSection);
  137.    if (hglb == NULL) goto ReleaseStream; 
  138.    lpSumInfo = (LPSUMINFO) GlobalLock(hglb);
  139.    if (lpSumInfo == NULL) goto Free;
  140.  
  141.    hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL);
  142.    if (hr != NOERROR) goto Unlock;
  143.    
  144.    hr = pIStream->Read(lpSumInfo, dwBytesInSection, &ulBytesRead);
  145.    if (hr != NOERROR || ulBytesRead > dwBytesInSection) goto Unlock;
  146.    // tbd: dwBytesInSection is long by 4 bytes for some Excel 5.0 files, so just
  147.    // check that ulBytesRead is <= dwBytesInSection and not that they are equal
  148.    
  149.    GlobalUnlock(hglb);
  150.    
  151.    goto ReleaseStream;  
  152.    
  153. Unlock:
  154.    GlobalUnlock(hglb);
  155.    
  156. Free:   
  157.    GlobalFree(hglb);
  158.    hglb = NULL;
  159.    
  160. ReleaseStream:                   
  161.    pIStream->Release();
  162.    
  163. ReleaseStorage:
  164.    pIStorage->Release();
  165.  
  166.    return hglb;       
  167. }
  168.  
  169. ///////////////////////////////////////////////////////////////////////////
  170. extern "C" void FAR PASCAL __export SumInfoCloseFile(HANDLE hSumInfo)
  171. {
  172.    GlobalFree(hSumInfo);
  173. }
  174.  
  175. ///////////////////////////////////////////////////////////////////////////
  176. extern "C" BOOL FAR PASCAL __export SumInfoGetString(HANDLE       hSumInfo,
  177.                                                      DWORD        pid,
  178.                                                      LPSTR        lpStr,
  179.                                                      int          cbStr)
  180. {
  181.    LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
  182.    if (lpProp == NULL) return FALSE;
  183.    if (lpProp->vtType != VT_LPSTR) return FALSE;
  184.    int len = (int) lpProp->vtValue.vtBSTR.cBytes;
  185.    if (len > cbStr) len = cbStr;
  186.    if (len <= 0) {
  187.       *(lpStr) = '\0';
  188.    }
  189.    else {
  190.       lstrcpyn(lpStr, lpProp->vtValue.vtBSTR.ch, len);
  191.       *(lpStr + len - 1) = '\0'; // len includes terminating null
  192.    }
  193.    return TRUE;
  194. }
  195.  
  196. ///////////////////////////////////////////////////////////////////////////
  197. extern "C" BOOL FAR PASCAL __export SumInfoGetLong(HANDLE       hSumInfo,
  198.                                                    DWORD        pid,
  199.                                                    LPLONG       lpLong)
  200. {
  201.    LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
  202.    if (lpProp == NULL) return FALSE;
  203.    if (lpProp->vtType != VT_I4) return FALSE;
  204.    *lpLong = lpProp->vtValue.vtLong;
  205.    return TRUE;
  206. }
  207.  
  208. ///////////////////////////////////////////////////////////////////////////
  209. extern "C" BOOL FAR PASCAL __export SumInfoGetTime(HANDLE       hSumInfo,
  210.                                                    DWORD        pid,
  211.                                                    LPWORD       yr,
  212.                                                    LPWORD       mon,
  213.                                                    LPWORD       day,
  214.                                                    LPWORD       hr,
  215.                                                    LPWORD       min,
  216.                                                    LPWORD       sec)
  217. {                                                       
  218.    struct {
  219.       unsigned int day : 5;
  220.       unsigned int mon : 4;
  221.       unsigned int yr  : 7;
  222.    } DosDate;
  223.    struct {
  224.       unsigned int sec2 : 5;
  225.       unsigned int min  : 6;
  226.       unsigned int hr   : 5;
  227.    } DosTime; 
  228.    
  229.    LPPROPVALUE lpProp = FindProperty(hSumInfo, pid);
  230.    if (lpProp == NULL) return FALSE;
  231.    if (lpProp->vtType != VT_FILETIME) return FALSE;
  232.    if (!CoFileTimeToDosDateTime(&lpProp->vtValue.vtTime,
  233.                                 (LPWORD) &DosDate, (LPWORD) &DosTime))
  234.       return FALSE;
  235.    *yr  = (WORD) DosDate.yr + 1980;
  236.    *mon = (WORD) DosDate.mon;
  237.    *day = (WORD) DosDate.day;
  238.    *hr  = (WORD) DosTime.hr;
  239.    *min = (WORD) DosTime.min;
  240.    *sec = (WORD) DosTime.sec2 * 2;
  241.    return TRUE;
  242. }
  243.  
  244. ///////////////////////////////////////////////////////////////////////////
  245. LPPROPVALUE FindProperty(HANDLE hSumInfo, DWORD pid)
  246. {
  247.    LPPROPVALUE lpProp;
  248.    DWORD i;
  249.    LPSUMINFO lpSumInfo = (LPSUMINFO) GlobalLock(hSumInfo);
  250.    if (lpSumInfo == NULL) return FALSE;
  251.    for (i = 0; i < lpSumInfo->cProps; i++) {
  252.       if (lpSumInfo->aProps[i].propID == pid) {
  253.          lpProp = (LPPROPVALUE) ((LPBYTE) lpSumInfo +
  254.                                  lpSumInfo->aProps[i].dwOffset);
  255.          GlobalUnlock(hSumInfo);
  256.          return lpProp;
  257.       }
  258.    }                      
  259.    GlobalUnlock(hSumInfo);
  260.    return NULL;
  261. }
  262.